﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;

namespace Frame
{
    public class DirectoryHelper
    {

        /// <summary>
        /// 获取子文件
        /// </summary>
        /// <param name="rootPath"></param>
        /// <returns></returns>
        public static string[] GetSubDirectory(string rootPath)
        {
            return GetSubFile(rootPath).ToArray();
        }
        /// <summary>
        /// 获取子文件
        /// </summary>
        /// <param name="rootPath">根目录</param>
        /// <returns></returns>
        public static List<string> GetSubFile(string rootPath)
        {
            try
            {
                List<string> pathList = new List<string>();
                DirectoryInfo directory = new DirectoryInfo(rootPath);
                FileInfo[] files = directory.GetFiles("*.*", SearchOption.AllDirectories);
                // 创建一个字符串数组来存储文件路径
                foreach (FileInfo fileinfo in files)
                {
                    string file = fileinfo.FullName;
                    string rootName = GetDirectoryName(file.Substring(0, file.LastIndexOf("\\")));
                    if (rootName == GetDirectoryName(rootPath))
                        continue;
                    pathList.Add(file);
                }
                return pathList;
            }
            catch (Exception)
            {
                return new List<string>();
            }
        }

        /// <summary> 
        /// 获取目录名称
        /// </summary> 
        /// <param name="directory"></param> 
        /// <returns></returns> 
        public static string GetDirectoryName(string directory)
        {
            if (!Directory.Exists(directory))
            {
                return string.Empty;// DirectoryHelper.CreateDirectory(directory); 
            }
            return new DirectoryInfo(directory).Name;
        }
        /// <summary>
        /// 获取根目录
        /// </summary>
        /// <param name="path">当前文件路径</param>
        /// <returns></returns>
        public static string GetRootDirectory(string path)
        {
            return path.Substring(0, path.LastIndexOf("\\"));
        }
        /// <summary>
        /// 删除空白文件夹
        /// </summary>
        /// <param name="rootPath"></param>
        public static void DeleteEmptyFolders(string rootPath)
        {

            // 获取目录中的所有子文件夹
            string[] subdirectories = Directory.GetDirectories(rootPath);

            foreach (string subdirectory in subdirectories)
            {
                // 递归调用删除空文件夹函数
                DeleteEmptyFolders(subdirectory);

                // 判断当前文件夹是否为空
                if (!Directory.EnumerateFileSystemEntries(subdirectory).Any())
                {
                    // 删除空文件夹
                    Directory.Delete(subdirectory);
                }
            }
        }
        /// <summary>
        /// 文件重命名
        /// </summary>
        /// <param name="targetDirectory">目标文件</param>
        /// <param name="filePath">文件目录</param>
        /// <returns></returns>
        public static string Rename(string targetDirectory, string filePath)
        {
            if (string.IsNullOrWhiteSpace(filePath))
            {
                return string.Empty;
            }

            string lastName = Path.GetFileName(filePath);
            if (Path.GetFileNameWithoutExtension(filePath) == "1-")
            {
                string lastDirName = GetDirectoryName(filePath.Substring(0, filePath.LastIndexOf("\\")));
                string s = Path.GetExtension(filePath);
                lastName = lastDirName + s;
            }

            //string newDirPath = filePath.Substring(0, targetDirectory.LastIndexOf("\\")) + "\\" + lastDirName;
            string newDirPath = targetDirectory + "\\" + lastName;
            return newDirPath;
        }

        /// <summary>
        /// 遍历所有的指定路径的子文件与文件夹，只保留指令扩展名的子文件，同时有一个ListBox控件，如果子文件的名称中包含listbox里项的字符串，也删除这个子文件
        /// </summary>
        /// <param name="path">根目录</param>
        /// <param name="extensions">扩展名</param>
        /// <param name="listBoxItems">包含字符串名</param>
        public static void TraverseAndRemove(string path, List<string> extensions, List<string> listBoxItems)
        {
            // 如果扩展名的第一位没有点，则添加点
            for (int i = 0; i < extensions.Count; i++)
            {
                if (!extensions[i].StartsWith("."))
                {
                    extensions[i] = "." + extensions[i];
                }
            }

            // 获取当前路径下的所有文件和文件夹
            DirectoryInfo directoryInfo = new DirectoryInfo(path);
            FileInfo[] files = directoryInfo.GetFiles();
            DirectoryInfo[] directories = directoryInfo.GetDirectories();

            // 遍历文件
            foreach (FileInfo file in files)
            {
                // 判断文件扩展名是否在 extensions 列表中
                if (!extensions.Contains(file.Extension))
                {
                    file.Delete();
                }
                // 判断文件名是否包含 listBoxItems 中的项
                else if (listBoxItems.Any(item => file.Name.Contains(item)))
                {
                    file.Delete();
                }
            }

            // 遍历文件夹
            foreach (DirectoryInfo directory in directories)
            {
                TraverseAndRemove(directory.FullName, extensions, listBoxItems);
            }
        }

        /// <summary>
        /// 运动行EXE
        /// </summary>
        /// <param name="path">EXE所有目录</param>
        public static void RunExe(string path)
        {

            if (File.Exists(path))
            {
                //Process process = new Process();   // params 为 string 类型的参数，多个参数以空格分隔，如果某个参数为空，可以传入””
                //ProcessStartInfo startInfo = new ProcessStartInfo(path, "");
                //process.StartInfo = startInfo;
                //process.Start();

                Process.Start(new ProcessStartInfo(path) { UseShellExecute = true });
            }
        }

        public static readonly Guid CLSID_WshShell = new Guid("72C24DD5-D70A-438B-8A42-98424B88AFB8");
        public static string GetShortCutTarget(string lnk) // 取快捷方式目标
        {
            if (lnk != null && System.IO.File.Exists(lnk))
            {
                dynamic objWshShell = null, objShortcut = null;
                try
                {
                    objWshShell = Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_WshShell));
                    objShortcut = objWshShell.CreateShortcut(lnk);
                    Console.WriteLine(objShortcut.TargetPath);
                    return objShortcut.TargetPath;
                }
                finally
                {
                    Marshal.ReleaseComObject(objShortcut);
                    Marshal.ReleaseComObject(objWshShell);
                }
            }
            return string.Empty;
        }
        
        /// <summary>
        /// 将子文件夹中的所有子文件移动到目标目录中，目标目录中存在一样的文件就加一个序号
        /// </summary>
        /// <param name="sourceFolder">源文件夹</param>
        /// <param name="destinationFolder">目标文件夹</param>
        public static void MoveFiles(string sourceFolder, string destinationFolder)
        {

            // 检查源文件夹路径是否合法
            if (!IsValidPath(sourceFolder))
            {
                Console.WriteLine($"源文件夹路径包含非法字符: {sourceFolder}");
                return;
            }

            // 检查目标文件夹路径是否合法
            if (!IsValidPath(destinationFolder))
            {
                Console.WriteLine($"目标文件夹路径包含非法字符: {destinationFolder}");
                return;
            }

            // 遍历源文件夹及其子文件夹
            foreach (string folderPath in Directory.GetDirectories(sourceFolder, "*", SearchOption.AllDirectories))
            {
                MoveFiles(folderPath, destinationFolder);
            }

            // 遍历源文件夹中的文件
            foreach (string filePath in Directory.GetFiles(sourceFolder))
            {
                string fileName = Path.GetFileName(filePath);
                string destinationPath = Path.Combine(destinationFolder, fileName);

                // 如果目标文件夹中存在同名文件，则添加序号
                int fileIndex = 1;
                while (File.Exists(destinationPath))
                {
                    string newFileName = $"{Path.GetFileNameWithoutExtension(fileName)}_{fileIndex}{Path.GetExtension(fileName)}";
                    destinationPath = Path.Combine(destinationFolder, newFileName);
                    fileIndex++;
                }

                File.Move(filePath, destinationPath);
            }
        }
        /// <summary>
        /// // 检查文件夹路径是否合法
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        private static bool IsValidPath(string path)
        {
            try
            {
                // 尝试获取路径的完整路径，如果抛出异常则说明路径不合法
                Path.GetFullPath(path);
                // 进一步检查路径中是否包含非法字符
                char[] invalidChars = Path.GetInvalidPathChars();
                foreach (char c in path)
                {
                    if (Array.IndexOf(invalidChars, c) >= 0)
                    {
                        return false;
                    }
                }
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        /// <summary>
        /// 判断一个目录是否只有一个子文件或没有子文件夹
        /// </summary>
        /// <param name="directoryPath"></param>
        /// <returns></returns>
        public static bool HasOnlyOneSubfileAndNoSubfolder(string directoryPath)
        {
            string[] entries = Directory.GetFileSystemEntries(directoryPath);
            int fileCount = 0;
            int folderCount = 0;

            foreach (string entry in entries)
            {
                if (File.Exists(entry))
                {
                    fileCount++;
                }
                else if (Directory.Exists(entry))
                {
                    folderCount++;
                }
            }

            return fileCount == 1 && folderCount == 0;
        }

    }
}
